Skip to content

Raspbian trixie#1106

Draft
SteveMicroNova wants to merge 36 commits into
mainfrom
RaspbianTrixie
Draft

Raspbian trixie#1106
SteveMicroNova wants to merge 36 commits into
mainfrom
RaspbianTrixie

Conversation

@SteveMicroNova

@SteveMicroNova SteveMicroNova commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What does this change intend to accomplish?

This is a reworking of AmpliPi to function in a 64 bit raspbian trixie A:B tryboot setup with the goal of having a more robust system overall and a cleaner update flow with full image updates

A few things that need to be worked on yet:

  • Ensure that LMS config and plugins persist on slot-swap
  • Label the partitions something other than p1-7

Checklist

  • Have you tested your changes and ensured they work?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • If applicable, have you updated the documentation/manual?
  • If applicable, have you updated the CHANGELOG?
  • Does your submission pass linting & tests? You can test on localhost using ./scripts/test
  • Have you written new tests for your core features/changes, as applicable?
  • If this is a UI change, have you tested it across multiple browser platforms on both desktop and mobile?

…ure.py to better handle installs from point 0 as well as better handle updates with this new OS
Update check_pass to explicitly use python 3.8 instead of python 3.13
add with_alsa flag to configure.py to optionally forcefully override
Add "dep filter" repeatable flag for the deploy script for rapid iteration while working on specific dependency install steps
Update NEW_RELEASE.md with a personal reminder
Update check_pass to explicitly use python 3.8 instead of python 3.13
add with_alsa flag to configure.py to optionally forcefully override
Fix alsa option in deploy script
…py with optional verbose logging during the debian upgrade portion
Fix asgi.py image consumption endpoint to only modify boot when needed as well as patch the fstab and journal entries for bootability
Move all services from `--user pi` to root to allow for reasonable ownership management between multiple OS instances

Add postflash service that validates that apt packages are properly installed

Fix small bug with LMS album art
@SteveMicroNova

SteveMicroNova commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

This is a WIP that will take a while to finish

This will change the baseline partition scheme of amplipi from basic boot+root to a 7 partition schema:

  • p1: Autoboot (raspberry pi A:B boot necessity), mounted as /boot/firmware
  • p2: Boot partition A
  • p3: Boot partition B
  • p4: Extended partition containing partitions 5, 6, and 7
  • p5: Root partition A
  • p6: Root partition B
  • p7: Persistent data storage for things that need to remain during flash, such as the user's config. Mounted at /data

Currently, I have the ability to update from images via the updater/asgi.py /update/flash endpoint that takes an update package: a folder containing a root image, an optional boot image, and a manifest.json file that describes the update package with a bytesize and sha256 checksum of the images.
This endpoint uses that update package to first verify the checksum of the image(s) before flashing, and then flashes the inactive directory. After flashing is complete, it also writes an "update-pending" file to p1 that signals to the update finalization service that things are freshly flashed and need to be checked on reboot.
Once that's all done, it also runs sudo reboot "0 tryboot" to move to the other slot

Once in the other boot+root slot, the update verification service checks to see if that /boot/firmware/update-pending file exists and if yes, runs a preflight check before allowing amplipi to start up - verifying if all the apt and python packages are properly in place. Once that's done and amplipi runs, it also edits /boot/firmware/autoboot.txt to change the newly flashed boot slot to be the new default slot so that the user doesn't revert to the previous slot on next reboot

@@ -1,4 +1,4 @@
#!/usr/bin/env python3

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version of python we run has to be installed via UV on Trixie, so I had to move the invocation paths on a few files

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we replace this with something more generic like uv run?

Comment thread amplipi/display/common.py
the stored default AmpliPi password."""

# Password config location
PASS_DIR = os.path.join(os.path.expanduser('~'), '.config', 'amplipi')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole .config folder and a few services got moved to /data to ensure they persist post-update, many lines like this had to be changed as a result

Comment thread config/autoboot.txt
Comment on lines +1 to +13
[all]
tryboot_a_b=1
boot_partition=2

[tryboot]
boot_partition=3

if exist mmc 0:1 /boot_partition.txt then
load mmc 0:1 ${loadaddr} /boot_partition.txt
env import -t ${loadaddr} ${filesize}
fi

boot mmc 0:${boot_partition}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the default autoboot.txt, which is what the update verification service edits when an update is successful. Specifically what is changed is swapping the [all] boot_partition value with the [tryboot] boot_partition value, that's all it takes to swap the default boot slot

Comment thread docs/imaging_etcher.md
* A micro USB cable
* Your AmpliPi

## Optional Step: Preserve your config

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file likely needs more reworking as realistically you shouldn't need to flash ever again, though also I'd say that makes more sense to leave until this code is in the hands of users and has a few support cases under its belt to verify if that's necessary

Comment on lines +33 to +41
# Run device-specific customization scripts from p7.
# These survive OTA updates and are re-applied on each new slot's first boot.
if [ -d "${SCRIPTS_DIR}" ]; then
for script in "${SCRIPTS_DIR}"/*.sh; do
[ -f "${script}" ] || continue
log "Running ${script}..."
bash "${script}" || log "Warning: ${script} exited non-zero"
done
fi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some users have specific setups on their devices that we don't want to destroy on a full-image update, so I've given them a directory that they can fill with bash scripts to set up their services automatically post-update

I need to test what happens if a user provides scripts that fail for those cases

Comment thread scripts/bootstrap_pi
--hostname NAME: The hostname to set on the pi, so once this script
successfully completes connect via {hostname}.local.
Default is amplipi
--cli-only: Use the lite version of Raspberry Pi OS which does not have

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point, CLI only became a default case for our units. I decided to flip the default case in this script to reflect that

Comment thread scripts/bootstrap_pi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file either needs full reworking or deletion. The new 7 partition setup is complex enough that updating this is a bit of a lift when we hardly need it and can also just distribute a full 7 partition image for those who need that sort of thing

@SteveMicroNova SteveMicroNova Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer is reworking. It won't be a simple portion, but creating a clean image that isn't mucked up with any dev happenings is an important goal and this script is likely one of the better ways to achieve that

Comment thread scripts/configure.py

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike bootstrap.py, I'd say configure.py is still very useful despite not being our update path anymore. manual deploys with the deploy+configure script are likely to be the primary ways we configure the root partitions that later get snapshotted into an image we distribute as an update

Comment thread amplipi/ctrl.py
vol, vol_f, vol_f_delta, vol_min, or vol_max.
"""
# Field precedence: vol (db) > vol_delta > vol (float)
# vol (db) is first in precedence yet last in the stack to cover the default case of no volume change

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a rebase error. This branch is long lived and had some merge conflicts on rebase and so may need to be combed for reversions like this before merging

Comment thread amplipi/rt.py
Comment on lines +286 to +289
try:
self.bus.close()
except Exception:
pass

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an additional fix for the issue fixed by #1098 which was merged in #1091

My unit actually got into a bad state during testing, which led to me having the ability to test those changes and add a little more to the fix

My own issue was downstream of some configuration file providing an environment that the I2C didn't like

Comment thread scripts/bootstrap_pi
Comment on lines +309 to 336
5. (Optional) Run the cleanup script to make the system 'factory fresh' with a randomgen ssh password and empty logs
"


echo "
NOTE: a modern AmpliPi setup is more complicated than simple bash scripting will allow, to match what a normal Pi would contain please follow the above directions, and then:
1. use `sudo dd if=/dev/sdx1 of=amplipi-boot.img status=progress bs=4MiB` to make an image of your boot directory, changing sdx into whatever sd your device mounted to
2. use `sudo dd if=/dev/sdx2 of=amplipi-root.img status=progress bs=4MiB` to make an image of your root directory, changing sdx into whatever sd your device mounted to
3. use parted or gparted to wipe all partitions and make the following partitions:

p1: FAT32, 516 MB, flash with amplipi-boot.img
p2: FAT32, 516 MB, flash with amplipi-boot.img
p3: FAT32, 516 MB, flash with amplipi-boot.img
p4: Extended partition containing p5-7 containing remainder of disk
p5: EXT4, 10939 MB, flash with amplipi-root.img
p6: EXT4, 10939 MB, flash with amplipi-root.img
p7: EXT4, sized to fill the remaining space

4. Edit the contents of the partitions as so:

p1: add autoboot.txt as seen in /config/autoboot.txt
p2: adjust cmdline.txt to point to partition 5
p3: adjust cmdline.txt to point to partition 6

p5: Add p7 to fstab as /data
p6: Add p7 to fstab as /data
p7: create a .config folder
"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is useful documentation for someone who might be trying to get their bearings on this PR

@SteveMicroNova SteveMicroNova Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also worth noting that this section isn't useful as a guide to get a unit up and running anymore

As I've continued working I've found more specific details that simply will not be captured here due to being things like "go deep into this directory and change this line in a random config file that I don't remember anymore"

Comment thread config/autoboot.txt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just considered that this file needs a greater explanation

The official docs are a bit sparse (or were when I first read them months ago), so I'll also explain myself:

tryboot_a_b=1 activates the tryboot mechanism, something supported in the raspbian kernel that allows for partition swapping using the command sudo reboot "0 tryboot". Using specifically that "0 tryboot" arg is how you boot into the partition listed under the [tryboot] boot_partition section.

That "0 tryboot" arg simply loads the boot partition listed under the [tryboot] header, it does not toggle anything in this file to make that partition the new default (which is handled by the amplipi-postflash service I've made), so doing a simple sudo reboot from the tryboot partition will send you back to whatever partition is listed under the [all] header

All the actual lifting is done by the individual boot partitions, which have their own kernels and mappings to their own root partitions

Comment thread config/autoboot.txt
Comment on lines +8 to +13
if exist mmc 0:1 /boot_partition.txt then
load mmc 0:1 ${loadaddr} /boot_partition.txt
env import -t ${loadaddr} ${filesize}
fi

boot mmc 0:${boot_partition}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This specific section may not be useful anymore, I'll have to do some testing without it

This was from a time when I was trying to have the boot_partitions be swapped without having a dedicated service for that purpose

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants